// src/utils/request.ts
import axios from 'axios';
import type { AxiosInstance, AxiosRequestConfig, AxiosResponse, InternalAxiosRequestConfig } from 'axios';

// 定义接口响应数据的标准格式
export interface ApiResponse<T = any> {
  code: number;
  data: T;
  message: string;
  success: boolean;
}

// 扩展AxiosRequestConfig，添加自定义配置选项
export interface RequestConfig extends AxiosRequestConfig {
  // 是否显示加载提示
  showLoading?: boolean;
  // 是否显示错误提示
  showError?: boolean;
  // 自定义错误处理函数
  customErrorHandler?: (error: any) => void;
}

class Request {
  private instance: AxiosInstance;
  private defaultConfig: RequestConfig = {
    baseURL: import.meta.env.VITE_API_BASE_URL as string || '/api',
    timeout: 10000,
    showLoading: true,
    showError: true,
  };

  constructor(config?: RequestConfig) {
    // 合并默认配置和传入配置
    this.instance = axios.create({ ...this.defaultConfig, ...config });
    this.setupInterceptors();
  }

  // 设置拦截器
  private setupInterceptors() {
    // 请求拦截器
    this.instance.interceptors.request.use(
      (config: InternalAxiosRequestConfig) => {
        // 在发送请求之前做些什么
        if ((config as RequestConfig).showLoading) {
          // 显示加载提示，这里可以使用你喜欢的UI库
          console.log('显示加载中...');
        }

        // 添加认证令牌
        const token = localStorage.getItem('token');
        if (token) {
          config.headers.Authorization = `Bearer ${token}`;
        }

        return config;
      },
      (error: any) => {
        // 对请求错误做些什么
        if (error.config?.showLoading) {
          // 隐藏加载提示
          console.log('隐藏加载中...');
        }
        return Promise.reject(error);
      }
    );

    // 响应拦截器
    this.instance.interceptors.response.use(
      (response: AxiosResponse) => {
        // 对响应数据做点什么
        if ((response.config as RequestConfig).showLoading) {
          // 隐藏加载提示
          console.log('隐藏加载中...');
        }

        // 根据后端返回的数据结构进行调整
        if (response.data.code === 200 || response.data.success) {
          return response.data;
        } else {
          // 业务逻辑错误
          this.handleError(response.data, response.config);
          return Promise.reject(response.data);
        }
      },
      (error: any) => {
        // 对响应错误做点什么
        if (error.config?.showLoading) {
          // 隐藏加载提示
          console.log('隐藏加载中...');
        }

        this.handleError(error, error.config);
        return Promise.reject(error);
      }
    );
  }

  // 错误处理
  private handleError(error: any, config?: RequestConfig) {
    // 如果配置了自定义错误处理，使用自定义处理
    if (config?.customErrorHandler) {
      config.customErrorHandler(error);
      return;
    }

    // 默认错误处理
    if (config?.showError) {
      let message = '请求错误';

      if (error.response) {
        // 服务器返回了错误状态码
        switch (error.response.status) {
          case 400:
            message = '请求错误';
            break;
          case 401:
            message = '未授权，请重新登录';
            // 清除token并跳转到登录页
            localStorage.removeItem('token');
            window.location.href = '/login';
            break;
          case 403:
            message = '拒绝访问';
            break;
          case 404:
            message = '请求资源未找到';
            break;
          case 500:
            message = '服务器内部错误';
            break;
          default:
            message = `连接错误${error.response.status}`;
        }
      } else if (error.request) {
        // 请求已经成功发起，但没有收到响应
        message = '网络连接异常，请检查网络';
      } else {
        // 发送请求时出了点问题
        message = error.message;
      }

      // 显示错误提示，这里可以使用你喜欢的UI库
      console.error('错误提示:', message);
    }
  }

  // 通用请求方法
  public request<T = any>(config: RequestConfig): Promise<ApiResponse<T>> {
    return this.instance.request(config);
  }

  // GET请求
  public get<T = any>(url: string, config?: RequestConfig): Promise<ApiResponse<T>> {
    return this.instance.get(url, config);
  }

  // POST请求
  public post<T = any>(url: string, data?: any, config?: RequestConfig): Promise<ApiResponse<T>> {
    return this.instance.post(url, data, config);
  }

  // PUT请求
  public put<T = any>(url: string, data?: any, config?: RequestConfig): Promise<ApiResponse<T>> {
    return this.instance.put(url, data, config);
  }

  // DELETE请求
  public delete<T = any>(url: string, config?: RequestConfig): Promise<ApiResponse<T>> {
    return this.instance.delete(url, config);
  }

  // PATCH请求
  public patch<T = any>(url: string, data?: any, config?: RequestConfig): Promise<ApiResponse<T>> {
    return this.instance.patch(url, data, config);
  }
}

// 创建请求实例
const request = new Request();

export default request;
